/*
 This file 'Firebird.App' is part of Firebird Integrated Solution 1.0

 Copyright (c) 2014 Lincong

 Contact:
 Email: lincong1987@gmail.com

 QQ: 159257119

 See Usage at http://www.jplatformx.com/firebird

 */
define(function (require, exports, module) {

	var global = this;

	var st = new Date().getTime();
	var _index = 0;

	require("Firebird.Model");
	require("Firebird.ui.Dialog");

	/**
	 * 抽象场景生成器
	 * @class Firebird.AbstractApp
	 */
	Firebird.define("Firebird.AbstractApp", {
		extend: "Firebird.Model",
		statics: {
			_uuid: 1,
			uuid: function () {
				return this._uuid++;
			}
		},

		/**
		 * idKey
		 */
		idKey: "id",

		/**
		 * 上下文对象
		 */
		context: {},

		/**
		 * 组件栈
		 */
		componentStack: [],

		/**
		 * 不自动渲染的元素
		 */
		norender: "fb-render",

		/**
		 * 属性观察
		 */
		observer: "fb-ui",

		/**
		 * 事件监听器
		 */
		listener: {
			"click::#J_query": "query",
			"click::#J_save": "save",
			"click::#J_edit": "edit",
			"click::#J_view": "view",
			"click::#J_delete": "delete",
			"click::#J_import": "import",
			"click::#J_export": "export",
			"click::#J_setup": "setup",
			"click::#J_keep": "keep",
			"click::#J_column": "column",
			"click::#J_reset": "reset"
		},

		handlers: {},

		config: {
			listener: null,
			handlers: null
		},

		/**
		 * 静态组件分析器
		 */
		componentsAnalyzer: function () {
			var me = this;
			me.uiComponents = $("[" + this.observer + "]");

			var components = ["Firebird.ui.FormValidator", "Firebird.ui.FormHelper"];

			$.each(me.uiComponents, function (index, component) {
				var observer = $(component).attr(me.observer).toLowerCase();
				switch (observer) {
					case"":
						break;
					case"conditions":
						components.push("Firebird.data.Conditions");
						break;
					case "datepicker":
						components.push("Firebird.ui.DatePicker");
						break;
					case "checkgroup":
						components.push("Firebird.ui.CheckGroup");
						break;
					case "office":
						components.push("Firebird.ui.Office");
						break;
					case "multiselecter":
						components.push("Firebird.ui.MultiSelecter");
						break;
					case "treeselecter":
						components.push("Firebird.ui.TreeSelecter");
						break;
					case "selecter":
						components.push("Firebird.ui.Selecter");
						break;
					case "singleselecter":
						components.push("Firebird.ui.SingleSelecter");
						break;
					case "suggestselecter":
						components.push("Firebird.ui.SuggestSelecter");
						break;
					case "suggestsingleselecter":
						components.push("Firebird.ui.SuggestSingleSelecter");
						break;
					case "dialogselecter":
						components.push("Firebird.ui.DialogSelecter");
						break;
					case "spinbox":
						components.push("Firebird.ui.Spinbox");
						break;
					case "grid":
						components.push("Firebird.ui.Grid");
						break;
					case "tree":
						components.push("Firebird.ui.Tree");
						break;
					case "treegrid":
						components.push("Firebird.ui.TreeGrid");
						break;
					case "textfield":
						components.push("Firebird.ui.TextField");
						break;
					case "numberfield":
						components.push("Firebird.ui.NumberField");
						break;
					case "textarea":
						components.push("Firebird.ui.TextArea");
						break;
					case "slider":
						components.push("Firebird.ui.Slider");
						break;
					case "doubleslider":
						components.push("Firebird.ui.DoubleSlider");
						break;
					case "button":
						components.push("Firebird.ui.Button");
						break;
					case "menubutton":
						components.push("Firebird.ui.MenuButton");
						break;
					case "toolbar":
						components.push("Firebird.ui.Toolbar");
						break;
					case "editor":
						components.push("Firebird.ui.Editor");
						break;
					case "echart":
						components.push("Firebird.ui.EChart");
						break;
					case "echartsimple":
						components.push("Firebird.ui.EChartSimple");
						break;
					case "echartcommon":
						components.push("Firebird.ui.EChartCommon");
						break;
					case "echartbmap":
						components.push("Firebird.ui.EChartBmap");
						break;
					case "echartdatatool":
						components.push("Firebird.ui.EChartDataTool");
						break;
					case "attachment":
						components.push("Firebird.ui.Attachment");
						break;
					case "formvalidator":
						components.push("Firebird.ui.FormValidator");
						break;
					case "formhelper":
						components.push("Firebird.ui.FormHelper");
						break;
					case "tabbar":
						components.push("Firebird.ui.Tabbar");
						break;
					default :
						break;
				}

				if (observer.indexOf("-") > 0) {

					// selecter-role-admin -> SelecterRoleAdmin
					var alias = observer,
						clazz = firebird.string.toCamel("_" + alias);
					firebird.info(alias, " -> ", clazz);
					components.push(clazz);
				}

				// if(observer === "formhelper"){
				//
				// }

			});

			components = Firebird.Array.unique(components);
			firebird.info("[Firebird.ui.ComponentLoader] 页面组件分析，需要加载: \n" + components.join(", \n"));

			me.loader(components, function () {
				me.initComponents();

				this.handlers = this.handlers || {};

				// 递归查找当前祖先类中的监听器
				function findSuper(clazz, thisClazz) {
					if (clazz.superclass && clazz.superclass.listener) {
						thisClazz.listener = $.extend({}, clazz.superclass.listener, thisClazz.listener);
						thisClazz.handlers = $.extend({}, clazz.superclass.handlers, thisClazz.handlers);
						findSuper(clazz.superclass, thisClazz);
					}
				}

				findSuper(me, me);

				me.attachListeners(me.listener);

				try {
					me.beforeLaunch.apply(me, [function () {
						me.setContext.apply(me, []);
						me.afterLaunch.apply(me, []);
					}]);
				} catch (ex) {
					firebird.error(ex);
				}
			});
		},
		/**
		 * 注册监听器
		 * @param listener
		 * @param handler
		 */
		attachListener: function (listener, handler) {
			var me = this;
			var event = "click", selector = "";
			if (listener.indexOf("::") != -1) {
				event = listener.split("::")[0];
				selector = listener.split("::")[1];
			} else {
				selector = listener;
			}

			// "click::#aaaa>>.ccc"

			if (selector != "") {
				firebird.info("listener::", event, ">", selector);
				handler = Firebird.isFunction(handler) ? (function () {
					me.handlers[selector] = handler;
					return handler;
				})() : (me.handlers[handler] || Firebird.emptyFn);

				if (context[selector]) {
					context[selector][event] = $.proxy(handler, me);
				} else {
					if (selector.indexOf(">>") != -1) {
						$(selector.split(">>")[0]).on(event, selector.split(">>")[1], {
							scope: me,
							app: me,
							context: me.context
						}, $.proxy(handler, me));
					} else {
						$(selector).on(event, {
							scope: me,
							app: me,
							context: me.context
						}, $.proxy(handler, me));
					}
				}
			}
		},
		/**
		 * 批量注册监听器
		 * @param listeners
		 * @returns {Firebird.AbstractApp}
		 */
		attachListeners: function (listeners) {
			var me = this;
			$.each(listeners, function (listener, handler) {
				me.attachListener.apply(me, [listener, handler]);
			});
			return me;
		},

		/**
		 * trigger
		 * @param handler
		 */
		trigger: function (handler) {
			if (this.handlers[handler]) {
				var args = firebird.toArray(arguments);
				args.shift();
				args.unshift({
					data: {
						app: this,
						context: this.context,
						controller: this.controller
					}
				});
				return this.handlers[handler].apply(this, args);
			} else {
				firebird.info(handler + " 未实现");
			}
		},
		/**
		 * 按需加载组件
		 * @param components
		 * @param nextCallback
		 */
		loader: function (components, nextCallback) {
			var me = this;
			//firebird.info("loading", components);
			require.async(components, function () {
				//firebird.info("loaded", components);
				nextCallback && nextCallback.apply(me, $.makeArray(arguments));
			});
		},

		/**
		 * 组件排序
		 */
		initComponentsSort: function () {
			var sst = new Date().getTime();
			var me = this;
			var len = me.uiComponents.length;
			var components = [];
			var lazy = [];
			for (var i = 0; i < len; i++) {
				if ($(me.uiComponents[i]).attr(me.observer).toLowerCase() == "formhelper" || $(me.uiComponents[i]).attr(me.observer).toLowerCase() == "tabbar") {
					lazy.push(me.uiComponents.get(i));
				} else {
					components.push(me.uiComponents.get(i));
				}
			}
			for (var i = 0; i < lazy.length; i++) {
				components.push(lazy[i]);
			}
			me.uiComponents = components;
			console.log("initComponentsSort", new Date().getTime() - sst)
		},

		/**
		 * 初始化组件
		 */
		initComponents: function () {
			var me = this;
			me.initComponentsSort();
			$.each(me.uiComponents, function (index, component) {

				var norender = $(component).attr(me.norender);

				if (norender && norender.toLowerCase() === "false") {
					return;
				}

				var observer = $(component).attr(me.observer).toLowerCase();

				switch (observer) {
					case "conditions":
						var conditions = Firebird.create("Firebird.data.Conditions", Firebird.data.Conditions.attrs($(component)));
						me.context[conditions.getInstanceId()] = conditions;
						me.componentStack.push(conditions);
						break;
					case "checkgroup":
						var checkgroup = Firebird.create("Firebird.ui.CheckGroup", Firebird.ui.CheckGroup.attrs($(component)));
						me.context[checkgroup.getInstanceId()] = checkgroup;
						me.componentStack.push(checkgroup);
						break;
					case "office":
						var office = Firebird.create("Firebird.ui.Office", Firebird.ui.Office.attrs($(component)));
						me.context[office.getInstanceId()] = office;
						me.componentStack.push(office);
						break;
					case "datepicker":
						var datepicker = Firebird.create("Firebird.ui.DatePicker", Firebird.ui.DatePicker.attrs($(component)));
						me.context[datepicker.getInstanceId()] = datepicker;
						me.componentStack.push(datepicker);
						break;
					case "multiselecter":
						var multiselecter = Firebird.create("Firebird.ui.MultiSelecter", Firebird.ui.MultiSelecter.attrs($(component)));
						me.context[multiselecter.getInstanceId()] = multiselecter;
						me.componentStack.push(multiselecter);
						break;
					case "treeselecter":
						var treeselecter = Firebird.create("Firebird.ui.TreeSelecter", Firebird.ui.TreeSelecter.attrs($(component)));
						me.context[treeselecter.getInstanceId()] = treeselecter;
						me.componentStack.push(treeselecter);
						break;
					case "selecter":
						var selecter = Firebird.create("Firebird.ui.Selecter", Firebird.ui.Selecter.attrs($(component)));
						me.context[selecter.getInstanceId()] = selecter;
						me.componentStack.push(selecter);
						break;
					case "singleselecter":
						var singleselecter = Firebird.create("Firebird.ui.SingleSelecter", Firebird.ui.SingleSelecter.attrs($(component)));
						me.context[singleselecter.getInstanceId()] = singleselecter;
						me.componentStack.push(singleselecter);
						break;
					case "suggestselecter":
						var suggestselecter = Firebird.create("Firebird.ui.SuggestSelecter", Firebird.ui.SuggestSelecter.attrs($(component)));
						me.context[suggestselecter.getInstanceId()] = suggestselecter;
						me.componentStack.push(suggestselecter);
						break;
					case "suggestsingleselecter":
						var suggestsingleselecter = Firebird.create("Firebird.ui.SuggestSingleSelecter", Firebird.ui.SuggestSingleSelecter.attrs($(component)));
						me.context[suggestsingleselecter.getInstanceId()] = suggestsingleselecter;
						me.componentStack.push(suggestsingleselecter);
						break;
					case "dialogselecter":
						var dialogselecter = Firebird.create("Firebird.ui.DialogSelecter", Firebird.ui.DialogSelecter.attrs($(component)));
						me.context[dialogselecter.getInstanceId()] = dialogselecter;
						me.componentStack.push(dialogselecter);
						break;
					case "spinbox":
						var spinbox = new Firebird.ui.Spinbox(Firebird.ui.Spinbox.attrs($(component)));
						me.context[spinbox.getInstanceId()] = spinbox;
						me.componentStack.push(spinbox);
						break;
					case "tree":
						var tree = Firebird.create("Firebird.ui.Tree", Firebird.ui.Tree.attrs($(component)));
						me.context[tree.getInstanceId()] = tree;
						me.componentStack.push(tree);
						break;
					case "textfield":
						var textfield = Firebird.create("Firebird.ui.TextField", Firebird.ui.TextField.attrs($(component)));
						me.context[textfield.getInstanceId()] = textfield;
						me.componentStack.push(textfield);
						break;
					case "numberfield":
						var numberfield = Firebird.create("Firebird.ui.NumberField", Firebird.ui.NumberField.attrs($(component)));
						me.context[numberfield.getInstanceId()] = numberfield;
						me.componentStack.push(numberfield);
						break;
					case "textarea":
						var textarea = Firebird.create("Firebird.ui.TextArea", Firebird.ui.TextArea.attrs($(component)));
						me.context[textarea.getInstanceId()] = textarea;
						me.componentStack.push(textarea);
						break;
					case "slider":
						var slider = Firebird.create("Firebird.ui.Slider", Firebird.ui.Slider.attrs($(component)));
						me.context[slider.getInstanceId()] = slider;
						me.componentStack.push(slider);
						break;
					case "doubleslider":
						var doubleslider = Firebird.create("Firebird.ui.DoubleSlider", Firebird.ui.DoubleSlider.attrs($(component)));
						me.context[doubleslider.getInstanceId()] = doubleslider;
						me.componentStack.push(doubleslider);
						break;
					case "button":
						var button = Firebird.create("Firebird.ui.Button", Firebird.ui.Button.attrs($(component)));
						me.context[button.getInstanceId()] = button;
						me.componentStack.push(button);
						break;
					case "menubutton":
						var menubutton = Firebird.create("Firebird.ui.MenuButton", Firebird.ui.MenuButton.attrs($(component)));
						me.context[menubutton.getInstanceId()] = menubutton;
						me.componentStack.push(menubutton);
						break;
					case "editor":
						var editor = Firebird.create("Firebird.ui.Editor", Firebird.ui.Editor.attrs($(component)));
						me.context[editor.getInstanceId()] = editor;
						me.componentStack.push(editor);
						break;
					case "echart":
						var echart = Firebird.create("Firebird.ui.EChart", Firebird.ui.EChart.attrs($(component)));
						me.context[echart.getInstanceId()] = echart;
						me.componentStack.push(echart);
						break;
					case "echartsimple":
						var echartsimple = Firebird.create("Firebird.ui.EChartSimple", Firebird.ui.EChartSimple.attrs($(component)));
						me.context[echartsimple.getInstanceId()] = echartsimple;
						me.componentStack.push(echartsimple);
						break;
					case "echartcommon":
						var echartcommon = Firebird.create("Firebird.ui.EChartCommon", Firebird.ui.EChartCommon.attrs($(component)));
						me.context[echartcommon.getInstanceId()] = echartcommon;
						me.componentStack.push(echartcommon);
						break;
					case "echartbmap":
						var echartbmap = Firebird.create("Firebird.ui.EChartBmap", Firebird.ui.EChartBmap.attrs($(component)));
						me.context[echartbmap.getInstanceId()] = echartbmap;
						me.componentStack.push(echartbmap);
						break;
					case "echartdatatool":
						var echartdatatool = Firebird.create("Firebird.ui.EChartDataTool", Firebird.ui.EChartDataTool.attrs($(component)));
						me.context[echartdatatool.getInstanceId()] = echartdatatool;
						me.componentStack.push(echartdatatool);
						break;
					case "attachment":
						var attachment = Firebird.create("Firebird.ui.Attachment", Firebird.ui.Attachment.attrs($(component)));
						me.context[attachment.getInstanceId()] = attachment;
						me.componentStack.push(attachment);
						break;
					case "formhelper":
						var formhelper = Firebird.create("Firebird.ui.FormHelper", Firebird.ui.FormHelper.attrs($(component)));
						me.context[formhelper.getInstanceId()] = formhelper;
						me.componentStack.push(formhelper);
						break;
					case "tabbar":
						var tabbar = Firebird.create("Firebird.ui.Tabbar", Firebird.ui.Tabbar.attrs($(component)));
						me.context[tabbar.getInstanceId()] = tabbar;
						me.componentStack.push(tabbar);
						break;
					//case "grid":
					//	var grid = Firebird.create("Firebird.ui.Grid");//, Firebird.ui.Grid.attrs($(component)));
					//	me.context[grid.getInstanceId()] = grid;
					//	me.componentStack.push(grid);
					//	break;
				}
				// });
				//
				// $.each(me.uiComponents, function (index, component) {
				if (observer.indexOf("-") > 0) {
					// if ($(component).attr(me.norender) && $(component).attr(me.norender).toLowerCase() == "false") {
					// 	return;
					// }
					var alias = observer,
						clazz = firebird.string.toCamel("_" + alias);
					if (!window[clazz]) {
						firebird.info("没有加载业务类: " + clazz + "。此组件将不自动实例化。");
					} else {
						var componenter = Firebird.create(clazz, window[clazz].attrs($(component)));
						me.context[componenter.getInstanceId()] = componenter;
						me.componentStack.push(componenter);
					}
				}
			});

		},

		/**
		 * 检查 Components Promise
		 * @param formHelper
		 * @param map
		 * @param done
		 */
		checkComponentsPromise: function (formHelper, map, done) {
			var me = this;

			// Promise 队列检查
			function doPromise() {
				var instanceList = [];
				$.each(formHelper.getValue(), function (name) {
					if (Firebird.isString(name)) {
						var target = $(formHelper.instance).find("[name='" + name + "']");
						if (target.data("xtype")
							&& target.data("xtype") == "selecter"
							|| target.data("xtype") == "multiselecter"
							|| target.data("xtype") == "treeselecter"
							|| target.data("xtype") == "singleselecter"
							|| target.data("xtype") == "checkgroup"
							|| target.data("xtype") == "tree") {
							if (target.data("instance")) {
								instanceList.push(target.data("instance")); 
							}
						}
					}
				});



				var i = 1;
				var intervalTimer = 160;
				if ($.browser.msie) {
					if ($.browser.version === "6.0") {
						intervalTimer = 160 * 5;
					}
					if ($.browser.version === "7.0") {
						intervalTimer = 160 * 3;
					}
					if ($.browser.version === "8.0") {
						intervalTimer = 160 * 2;
					}
				}
				var t = setInterval(function () {
					i++;     		_index++;
					console.log(_index) ;
					if (i >= 1000) {
						firebird.warn("warnning!! doPromiseCheck auto stop!");
						clearInterval(t);
						done && done();
						try {
							me.hideProgress();
						} catch (e) {
						}
					}
					if (allDone(instanceList, i) === true) {
						clearInterval(t);
						done && done();
						try {
							me.hideProgress();
						} catch (e) {
						}
					}
				}, intervalTimer);
			}

			// 返回 true 所有资源加载结束
			function allDone(instanceList, checkIndex) {
				// 假定资源未加载
				var flag = true;
				$.each(instanceList, function (i, instance) {
					// _index++;
					// console.log(_index) ;
					if (instance._remoteSuccess === false) {
						if ((checkIndex) % 160 == 0) {
							firebird.info("Firebird.App::doPromiseCheck " + instance.$className + "#" + instance.getInstanceId() + " is Not Ready", checkIndex);
						}
						flag = false;
						return false;
					}
				});
				return flag;
			}

			doPromise(formHelper, map, done);
		},
		/**
		 * 检查指定组件的数据加载状态
		 * @param componentIds
		 * @param map
		 * @param done
		 */
		checkComponentsLoad: function (componentIds, done) {
			var me = this;

			// Promise 队列检查
			function doPromise() {
				var instanceList = [];
				$.each($.isArray(componentIds) ? componentIds : [componentIds], function (i, name) {

					if (Firebird.isString(name)) {
						var target = context[name] && context[name].instance;
						if (!target) {
							target = $("[name='" + name + "']");
						}
						if (target.data("xtype")
							&& target.data("xtype") === "selecter"
							|| target.data("xtype") === "multiselecter"
							|| target.data("xtype") === "treeselecter"
							|| target.data("xtype") === "singleselecter"
							|| target.data("xtype") === "tree"
							|| target.data("xtype") === "gismanager") {
							if (target.data("instance")) {
								instanceList.push(target.data("instance"));
							}
						}
					} else if (Firebird.isObject(name)) {
						var target = name.instance;
						if (!target) {
							target = $("[name='" + name + "']");
						}
						if (target && target.data("xtype")
							&& target.data("xtype") === "selecter"
							|| target.data("xtype") === "multiselecter"
							|| target.data("xtype") === "treeselecter"
							|| target.data("xtype") === "singleselecter"
							|| target.data("xtype") === "tree"
							|| target.data("xtype") === "gismanager") {
							if (target.data("instance")) {
								instanceList.push(name);
							}
						}
					}
				});

				var i = 1;
				var t = setInterval(function () {
					i++;
					if (i >= 1000) {
						firebird.warn("warnning!! checkComponentsLoad auto stop!");
						clearInterval(t);
						done && done();
					}
					if (allDone(instanceList, i) == true) {
						clearInterval(t);
						done && done();
					}
				}, 16);
			}

			// 返回 true 所有资源加载结束
			function allDone(instanceList, checkIndex) {
				// 假定资源未加载
				var flag = true;
				$.each(instanceList, function (i, instance) {  		_index++;
					console.log(_index) ;
					if (instance._remoteSuccess === false) {
						if ((checkIndex) % 160 == 0) {
							firebird.info("Firebird.App::checkComponentsLoad " + instance.$className + "#" + instance.getInstanceId() + " is Not Ready", checkIndex);
						}
						flag = false;
						return false;
					}
				});
				return flag;
			}

			doPromise(componentIds, done);
		},
		ready: function () {

		},
		/**
		 *
		 * @param nextCallback
		 */
		beforeLaunch: function (nextCallback) {

			var me = this;
			var context = this.context;
			try {
				context.data = firebird.data.get(firebird.url.getParameter("_FBID_") || window.name) || {};
			} catch (e) {
			}
			nextCallback && nextCallback.apply(this, []);
		},
		afterLaunch: function () {
		},
		setContext: function () {
		},
		constructor: function (config) {
			this.initConfig(config);
			var uuid = Firebird.AbstractApp.uuid();
			window.app = this;
			window.context = this.context;
			window[$("[fb-ui=context]").attr("fb-app") || "app_" + this.$className.replace(/\./g, "_") + "_" + uuid] = this;
			window[$("[fb-ui=context]").attr("fb-context") || "context_" + this.$className.replace(/\./g, "_") + "_" + uuid] = this.context;
			this._init.apply(this, arguments);
			$(window).on("beforeunload", function (e) {
				$.each(window.context, function (comp, k) {
					try {
						comp.destroy();
						this.destroy();
						delete this;
					} catch (e) {
					}
				});
			});
		},
		_init: function () {
			this.componentsAnalyzer.apply(this);
			this.showProgress();
		},

		bindEditValidater: function () {
			var me = this, context = this.context;
			context.J_form.instance.isValid(function (result) {
				if (result == true) {
					var tip = Firebird.ui.Dialog.tips("正在处理修改操作...", 100000, {lock: true});
					me.controller.modify(context.J_form.getValue(), {}, function (data) {
						tip.remove();
						//firebird.info("Firebird.App::modify complete ", data);
						if (data.success === true) {
							me.context.dialog.close(data);
						} else {
							new Firebird.lang.AjaxException({
								message: data.data && data.data.replace(/\;/, ";\n")
							});
						}
					});
				}
			});
		},

		bindSaveValidater: function () {
			var me = this, context = this.context;
			context.J_form.instance.isValid(function (result) {
				if (result == true) {
					var tip = Firebird.ui.Dialog.tips("正在处理新增操作...", 100000, {lock: true});
					me.controller.insert(context.J_form.getValue(), {}, function (data) {
						tip.remove();
						//firebird.info("Firebird.App::insert complete ", data);
						if (data.success === true) {
							me.context.dialog.close(data);
						} else {
							new Firebird.lang.AjaxException({
								message: data.data && data.data.replace(/\;/, ";\n")
							});
						}
					});
				}
			});
		},

		setValue: function (callback) {
			var me = this;
			var context = this.context;
			// 有一个细节：上下文对象中有一个 data 属性, @see {@link Firebird.SearchApp}
			// context.data.context 是 调用链 中的 上一个 上下文对象
			me.controller.select(context.data.app.getActionIds()[0], {}, function (json) {
				me.checkComponentsPromise(context.J_form, json.data, function () {
					if (me.beforeSetValue.apply(me, [context.J_form, json.data]) == true) {
						context.J_form.setValue(json.data);
					}
					me.afterSetValue();
				});
			});
		},
		beforeSetValue: function () {
			return true;
		},
		afterSetValue: function () {
			
		},
		setButtons: function (buttons) {
			return buttons;
		},
		showProgress: function () {
			if (!this._mask) {
				this._mask = (_top.$.dialog && _top.$.dialog.list && _top.$.dialog.list["_wait_dialog"]) || _top.$.dialog.wait("请稍等，资源正在加载...", 10000, {
					id: "_wait_dialog",
					lock: true,
					// 设置遮罩背景颜色
					backdropBackground: '#fff',
					// 设置遮罩透明度
					backdropOpacity: 0
				});
			} else {
				this._mask.show();
			}
		},
		hideProgress: function () {
			var me = this;

			$("html").css("visibility", "visible");
			if (this._mask) {
				//me._mask.content("资源加载完成.");
				setTimeout(function () {
					me._mask && me._mask.remove();
					console.log(new Date().getTime() - st)
				}, 0);
			}
			if (me.context.dialog) {
				me.context.dialog && me.context.dialog.showModal && me.context.dialog.showModal();
			}

		},
		/**
		 * 返回查看动作的ID数组
		 * @param e {Event}
		 * @returns {*|Array}
		 */
		getActionIds: function (e) {
			return this.actionIds;
		},
		/**
		 * 设置动作的ID数组
		 * @param e
		 * @returns {Firebird.AbstractApp}
		 */
		setActionIds: function (e) {
			this.actionIds = this.context.J_grid.getCheckedRowIds();
			return this;
		}
	});

	/**
	 * Firebird.SearchApp
	 * @class Firebird.SearchApp
	 */
	Firebird.define("Firebird.SearchApp", {
		extend: "Firebird.AbstractApp",
		beforeLaunch: function (afterCallback) {
			afterCallback && afterCallback.apply(this, []);
		},
		afterLaunch: function () {
			this.hideProgress();
		},
		handlers: {
			query: function (e) {
				e.data.context.J_grid.query();
			},
			save: function (e) {
				var app = this;
				app.controller.save({app: this, context: this.context, title: "新增", lock: true}, function (operation) {
					if (operation.success) {
						Firebird.ui.Dialog.success("数据新增成功！", null, {time: 5000});
						app.context.J_grid.reload();
					}
				});
			},
			edit: function (e) {
				var app = this;
				//var ids = app.context.J_grid.getCheckedRowIds();
				app.setActionIds(e);
				var ids = app.getActionIds(e);
				if (ids.length != 1) {
					Firebird.ui.Dialog.warn("请选择一条数据进行操作！");
					return;
				}
				app.controller.edit(ids[0], {app: app, context: app.context, title: "修改"}, function (operation) {
					if (operation.success) {
						Firebird.ui.Dialog.success("数据修改成功！", null, {time: 5000});
						app.context.J_grid.reload();
					}
				});
			},
			view: function (e) {
				var app = this;
				app.setActionIds(e);
				var ids = app.getActionIds(e);
				if (ids.length != 1) {
					Firebird.ui.Dialog.warn("请选择一条数据进行查看！");
					return;
				}
				app.controller.view(ids[0], {app: app, context: app.context, title: "查看"}, function (operation) {
					if (operation.success) {
					}
				});
			},
			"delete": function (e) {
				var app = this;
				app.setActionIds(e);
				var ids = app.getActionIds(e);
				if (ids.length == 0) {
					Firebird.ui.Dialog.warn("请选择一条或多条数据进行操作。");
					return;
				}
				Firebird.ui.Dialog.confirm("数据即将被删除，请确认后操作。<br><br>点击【取消】，数据不会删除，点击【确认】，删除数据。", function () {
					app.controller.remove(ids, {app: app, context: app.context}, function (operation) {
						if (operation.success) {
							Firebird.ui.Dialog.success("数据已删除！", null, {time: 5000});
							app.context.J_grid.reload();
						}
					});
				});
			},
			"reset": function (e) {
				this.context.J_form.clear();
			}
		}
	});

	/**
	 * Firebird.SaveApp
	 * @class Firebird.SaveApp
	 */
	Firebird.define("Firebird.SaveApp", {
		extend: "Firebird.AbstractApp",
		afterLaunch: function () {
			var me = this;
			var context = this.context;

			context.data = firebird.data.get(firebird.url.getParameter("_FBID_") || window.name) || {};
			context.dialog = _top.$.dialog && _top.$.dialog.get(window) || require("dialog");
			context.dialog && context.dialog.button && context.dialog.button(me.setButtons([
				{
					value: "确 定",
					autofocus: true,
					callback: function () {
						me.bindSaveValidater();
						return false;
					}
				},
				{
					value: "取 消"
				}
			]));
			this.hideProgress();
		},

		handlers: {}
	});

	/**
	 * Firebird.EditApp
	 */
	Firebird.define("Firebird.EditApp", {
		extend: "Firebird.AbstractApp",
		afterLaunch: function () {
			var me = this;
			var context = this.context;
			context.data = firebird.data.get(firebird.url.getParameter("_FBID_") || window.name) || {};
			context.dialog = _top.$.dialog && _top.$.dialog.get(window) || require("dialog");
			context.dialog && context.dialog.button && context.dialog.button(me.setButtons([
				{
					value: "修 改",
					autofocus: true,
					callback: function () {
						me.bindEditValidater();
						return false;
					}
				},
				{
					value: "取 消"
				}
			]));
			this.setValue();
			this.hideProgress();
		},

		handlers: {}
	});

	/**
	 * Firebird.ViewApp
	 */
	Firebird.define("Firebird.ViewApp", {
		extend: "Firebird.AbstractApp",
		afterLaunch: function () {
			var me = this;
			var context = this.context;

			context.data = firebird.data.get(firebird.url.getParameter("_FBID_") || window.name) || {};
			context.dialog = _top.$.dialog && _top.$.dialog.get(window) || require("dialog");
			context.dialog && context.dialog.button && context.dialog.button(me.setButtons(
				[
					//{
					//	value: "关 闭",
					//	autofocus: true,
					//	callback: function () {
					//	}
					//}
				]
			));
			this.setValue();
			this.hideProgress();
		},
		handlers: {}
	});

	/**
	 * Firebird.TreeApp
	 */
	Firebird.define("Firebird.TreeApp", {
		extend: "Firebird.AbstractApp",
		listener: {
			"click::#J_save": "save",
			"click::#J_edit": "edit",
			"click::#J_delete": "delete",
			"click::#J_up": "up",
			"click::#J_down": "down",
			"click::#J_root": "root",
			"click::#J_cancel": "cancel"
		},
		handlers: {
			save: function (e) {
				var app = this;
				var nodes = context.J_tree.getSelectedNodes();
				if (nodes.length != 1) {
					Firebird.ui.Dialog.warn("请选择一个节点！");
					return;
				}
				var action = app.controller.getAction("pageSave");
				//
				firebird.data.set(action.uuid, {
					app: app,
					context: app.context,
					nodes: nodes,
					success: function (operation) {
						if (operation.success) {
							Firebird.ui.Dialog.success("新增节点成功！", null, {time: 5000});
							app.context.J_tree.zTreeInstance.reAsyncChildNodes(nodes[0], "refresh", false, function () {
								//var idKey = app.context.J_tree.getOptions().data.simpleData.idKey;
								//var newNodes = app.context.J_tree.zTreeInstance.getNodesByParam(idKey, nodes[0][idKey]);
								app.context.J_tree.zTreeInstance.selectNode(nodes[0]);
							});
						}
					}
				});
				this.context.J_form.html(require("tmpl").compile(""
					+ "<iframe"
					+ " src='{{url}}'"
					+ " frameborder=0"
					+ " width='100%' height='100%' "
					+ " name='{{name}}'"
					+ "></iframe>")({
					name: action.uuid,
					url: action.url + "?_FBID_=" + action.uuid
				}));
			},
			edit: function (e) {
				var app = this;
				var nodes = context.J_tree.getSelectedNodes();
				if (nodes.length != 1) {
					Firebird.ui.Dialog.warn("请选择一个节点！");
					return;
				}
				var action = app.controller.getAction("pageEdit");
				//
				firebird.data.set(action.uuid, {
					app: app,
					context: app.context,
					success: function (operation) {
						if (operation.success) {
							Firebird.ui.Dialog.success("编辑节点成功！", null, {time: 5000});
							var idKey = app.context.J_tree.getOptions().data.simpleData.idKey;
							app.controller.select(nodes[0][idKey], {}, function (json) {
								$.extend(nodes[0], json.data);
								app.context.J_tree.zTreeInstance.updateNode(nodes[0]);
							});

							//app.context.J_tree.zTreeInstance.reAsyncChildNodes(nodes[0].getParentNode(), "refresh", false, function () {
							//	var idKey = app.context.J_tree.getOptions().data.simpleData.idKey;
							//	var newNodes = app.context.J_tree.zTreeInstance.getNodesByParam(idKey, nodes[0][idKey]);
							//	app.context.J_tree.zTreeInstance.selectNode(newNodes[0]);
							//});
						}
					}
				});
				this.context.J_form.html(require("tmpl").compile(""
					+ "<iframe"
					+ " src='{{url}}'"
					+ " frameborder=0"
					+ " width='100%' height='100%' "
					+ " name='{{name}}'"
					+ "></iframe>")({
					name: action.uuid,
					url: action.url + "?_FBID_=" + action.uuid
				}));
			},
			"delete": function (e) {
				var app = this;
				var controller = this.controller;
				var nodes = context.J_tree.getSelectedNodes();
				if (nodes.length == 0) {
					Firebird.ui.Dialog.warn("请选择一个节点。");
					return;
				}
				Firebird.ui.Dialog.confirm("数据即将被删除，请确认后操作。<br><br>点击【取消】，数据不会删除，点击【确认】，删除数据。", function () {
					var id = app.context.J_tree.getOptions().data.simpleData.idKey;
					controller.remove(nodes[0][id], {e: e}, function (operation) {
						if (operation.success) {
							Firebird.ui.Dialog.success("节点已删除！", null, {time: 5000});
							app.context.J_tree.zTreeInstance.removeChildNodes(nodes[0]);
							app.context.J_tree.zTreeInstance.removeNode(nodes[0]);
							app.context.J_tree.zTreeInstance.selectNode(nodes[0].getParentNode());
							app.trigger("cancel");
						}
					});
				});
			},
			cancel: function () {
				this.context.J_form.html(""
					+ "<div class='ui-tree-layout-east-form-title'>"
					+ "<span class=''>请选择节点</span>"
					+ "</div>");
			}
		},
		afterLaunch: function () {
			this.hideProgress();
			var me = this;
			var context = this.context;
		}
	});


	/**
	 * Firebird.BlankApp
	 */
	Firebird.define("Firebird.BlankApp", {
		extend: "Firebird.AbstractApp",
		afterLaunch: function () {
			var me = this;
			var context = this.context;

			context.data = firebird.data.get(firebird.url.getParameter("_FBID_") || window.name) || {};
			context.dialog = _top.$.dialog && _top.$.dialog.get(window) || require("dialog");
			context.dialog && context.dialog.button && context.dialog.button(me.setButtons(
				[
					//{
					//	value: "关 闭",
					//	autofocus: true,
					//	callback: function () {
					//	}
					//}
				]
			));
			this.setValue();
			this.hideProgress();
		},
		setValue: function () {

		},
		handlers: {}
	});


});